package com.rockwell.maze800;

import java.util.Arrays;
import java.util.List;

import com.rockwell.maze800.model.MazePath;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

public class PathActivity extends Activity {
	int m_maxRows = 60;

	private boolean m_editing = false;

	static final int COLUMN_DISTANCE = 1;
	static final int COLUMN_JUNCTION = 2;
	static final int COLUMN_DIRECTION = 3;

	static final Integer[] m_distances = new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	ArrayAdapter<Integer> m_distanceAdapter;
	
	OnClickListener m_junctionListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			if (m_editing) {
				View tr = (View) v.getParent();
				int row = Integer.parseInt((String) tr.getTag());
				onClickJunction(row);
			}
		}

	};

	OnClickListener m_actionListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			if (m_editing) {
				View tr = (View) v.getParent();
				int row = Integer.parseInt((String) tr.getTag());
				onClickAction(row);
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_path);

		m_distanceAdapter = new ArrayAdapter<Integer>(this,android.R.layout.simple_spinner_item, m_distances);
		
		m_maxRows = SettingsActivity.getMaximumSteps(this);
		
		initializePathTable();

		setupEditButton();
		setupSaveButton();
		setupClearButton();
		setupCloseButton();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.path, menu);
		return true;
	}

	private void setupEditButton() {
		Button bn = (Button) findViewById(R.id.button_edit);
		bn.setEnabled(true);

		bn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				enableEditing(true);
			}

		});
	}

	private void setupSaveButton() {
		Button bn = (Button) findViewById(R.id.button_save);
		bn.setEnabled(false);

		bn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				savePath();
				enableEditing(false);
			}

		});
	}

	private void setupClearButton() {
		Button bn = (Button) findViewById(R.id.button_clear);
		bn.setEnabled(false);

		bn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				clearAllRows();
			}

		});
	}
	
	private void setupCloseButton() {
		Button bn = (Button) findViewById(R.id.button_close);

		bn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Intent returnIntent = new Intent();
				setResult(RESULT_OK,returnIntent);     

				finish();
			}

		});
	}

	private void enableEditing(boolean b) {
		m_editing = b;

		Button edit = (Button) findViewById(R.id.button_edit);
		Button save = (Button) findViewById(R.id.button_save);
		Button clear = (Button) findViewById(R.id.button_clear);

		edit.setEnabled(!b);
		save.setEnabled(b);
		clear.setEnabled(b);
		
		TableLayout table = (TableLayout) findViewById(R.id.table_path);
		for (int i = 0; i < table.getChildCount(); i++) {
			TableRow tr = (TableRow) table.getChildAt(i);
			View dText = tr.getChildAt(COLUMN_DISTANCE);
			dText.setEnabled(b);
		}
	}

	private void savePath() {
		StringBuilder sb = new StringBuilder();
		TableLayout table = (TableLayout) findViewById(R.id.table_path);

		for (int i = 0; i < table.getChildCount(); i++) {
			TableRow tr = (TableRow) table.getChildAt(i);
			//EditText dText = (EditText)tr.getChildAt(COLUMN_DISTANCE);
			Spinner dText = (Spinner)tr.getChildAt(COLUMN_DISTANCE);
			ImageButton jButton = (ImageButton) tr.getChildAt(COLUMN_JUNCTION);
			ImageButton dButton = (ImageButton) tr.getChildAt(COLUMN_DIRECTION);

			String distance = Integer.toHexString(dText.getSelectedItemPosition());
			int junction = (Integer) jButton.getTag();
			int direction = (Integer) dButton.getTag();

			if (junction == 0 || direction == 0) {
				break;
			}

			sb.append(distance);
			sb.append(String.valueOf(junction));
			sb.append(String.valueOf(direction));
		}

		SettingsActivity.setPredefinedPath(this, sb.toString());
	}

	private void initializePathTable() {
		TableLayout table = (TableLayout) findViewById(R.id.table_path);
		table.setStretchAllColumns(true);

		Drawable[] junctionImages = new Drawable[MazePath.junctionIcons.length];
		for (int i = 0; i < junctionImages.length; i++) {
			junctionImages[i] = getResources().getDrawable(MazePath.junctionIcons[i]);
		}

		Drawable[] directionImages = new Drawable[MazePath.directionIcons.length];
		for (int i = 0; i < directionImages.length; i++) {
			directionImages[i] = getResources()
					.getDrawable(MazePath.directionIcons[i]);
		}

		LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);

		String path = SettingsActivity.getPredefinedPath(this);

		for (int i = 0; i < m_maxRows; i++) {
			TableRow row = new TableRow(this);
			String tag = Integer.toString(i);
			row.setTag(tag);

			int distance = 0;
			int jTag = 0;
			int dTag = 0;

			if (path.length() >= (i + 1) * 3) {
				distance = Integer.parseInt(String.valueOf(path.charAt(i * 3)), 16);
				jTag = Integer.valueOf(String.valueOf(path.charAt(i * 3 + 1)));
				dTag = Integer.valueOf(String.valueOf(path.charAt(i * 3 + 2)));
			}

			{
				TextView number = new TextView(this);
				number.setLayoutParams(params);
				number.setText(String.valueOf(i));
				row.addView(number);
			}
			{
				/*
				EditText edit = new EditText(this);
				edit.setText(String.valueOf(distance));
				edit.setEnabled(false);
				row.addView(edit);
				*/
				Spinner d = new Spinner(this);
				d.setLayoutParams(params);
				d.setAdapter(m_distanceAdapter);
				d.setSelection(distance);
				d.setEnabled(false);
				row.addView(d);
			}
			{
				ImageButton junction = new ImageButton(this);
				junction.setOnClickListener(m_junctionListener);

				junction.setImageDrawable(junctionImages[jTag]);
				junction.setTag(jTag);

				junction.setLayoutParams(params);
				row.addView(junction);
			}
			{
				ImageButton action = new ImageButton(this);
				action.setOnClickListener(m_actionListener);

				action.setImageDrawable(directionImages[dTag]);
				action.setTag(dTag);

				action.setLayoutParams(params);
				row.addView(action);
			}

			table.addView(row);
		}
	}

	private void clearAllRows() {
		TableLayout table = (TableLayout) findViewById(R.id.table_path);

		Drawable junctionIcon = getResources().getDrawable(MazePath.junctionIcons[0]);
		Drawable dirIcon = getResources().getDrawable(MazePath.directionIcons[0]);

		for (int i = 0; i < table.getChildCount(); i++) {
			TableRow tr = (TableRow) table.getChildAt(i);
			//EditText dText = (EditText)tr.getChildAt(COLUMN_DISTANCE);
			Spinner cells = (Spinner)tr.getChildAt(COLUMN_DISTANCE);
			cells.setSelection(0);
			
			ImageButton junction = (ImageButton) tr.getChildAt(COLUMN_JUNCTION);
			junction.setImageDrawable(junctionIcon);
			junction.setTag(0);
			
			ImageButton dir = (ImageButton) tr.getChildAt(COLUMN_DIRECTION);
			dir.setImageDrawable(dirIcon);
			dir.setTag(0);
		}
	}
	
	private void onClickJunction(final int row) {

		ListAdapter adapter = new IconArrayAdapter(this, MazePath.junctionTypes,
				MazePath.junctionIcons);

		new AlertDialog.Builder(this).setTitle("Select Junction Type")
				.setAdapter(adapter, new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog, int item) {
						changeJunctionType(row, item);
					}

				}).show();
	}

	private void onClickAction(final int row) {

		ListAdapter adapter = new IconArrayAdapter(this, MazePath.directionTypes,
				MazePath.directionIcons);

		new AlertDialog.Builder(this).setTitle("Select Direction")
				.setAdapter(adapter, new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog, int item) {
						changeDirectionType(row, item);
					}

				}).show();
	}

	private void changeJunctionType(int row, int type) {
		TableLayout table = (TableLayout) findViewById(R.id.table_path);
		TableRow tr = (TableRow) table.getChildAt(row);
		ImageButton bn = (ImageButton) tr.getChildAt(COLUMN_JUNCTION);

		Drawable image = getResources().getDrawable(MazePath.junctionIcons[type]);
		bn.setImageDrawable(image);
		bn.setTag(type);

		switch (type) {
		case 1:
			// left-turn only
			changeDirectionType(row, MazePath.DIRECTION_LEFT);
			break;

		case 2:
			// right-turn only
			changeDirectionType(row, MazePath.DIRECTION_RIGHT);
			break;
		}
	}

	private void changeDirectionType(int row, int type) {
		TableLayout table = (TableLayout) findViewById(R.id.table_path);
		TableRow tr = (TableRow) table.getChildAt(row);
		
		ImageButton junction = (ImageButton)tr.getChildAt(COLUMN_JUNCTION);
		int jTag = (Integer)junction.getTag();
		
		ImageButton direction = (ImageButton) tr.getChildAt(COLUMN_DIRECTION);

		if (MazePath.isValidDirection(jTag, type)) {
			Drawable image = getResources().getDrawable(MazePath.directionIcons[type]);
			direction.setImageDrawable(image);
			direction.setTag(type);
		}
		else {
			Toast.makeText(this, "Invalid direction", Toast.LENGTH_LONG).show();
		}
	}

	static class IconArrayAdapter extends ArrayAdapter<String> {
		private List<Integer> images;

		public IconArrayAdapter(Context context, List<String> items,
				List<Integer> images) {
			super(context, android.R.layout.select_dialog_item, items);
			this.images = images;
		}

		public IconArrayAdapter(Context context, String[] items,
				Integer[] images) {
			super(context, android.R.layout.select_dialog_item, items);
			this.images = Arrays.asList(images);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = super.getView(position, convertView, parent);
			TextView textView = (TextView) view
					.findViewById(android.R.id.text1);
			textView.setCompoundDrawablesWithIntrinsicBounds(
					images.get(position), 0, 0, 0);
			textView.setCompoundDrawablePadding((int) TypedValue
					.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12,
							getContext().getResources().getDisplayMetrics()));
			return view;
		}
	}
}
